package com.zlzlib.libdata.helper;

import android.os.Environment;

import com.zlzlib.libdata.util.MyDateTimeUtil;
import com.zlzlib.libdata.util.MyFileUtil;

import java.text.DateFormat;
import java.util.Date;

/**
 * 日志收集写入工具
 *
 * @DateTime: 2021/2/25 9:34
 * @Author zlz
 * @Version 1.0
 */
public final class LogHelper {

    private volatile static LogHelper instance = null;

    public static LogHelper getInstance() {
        if (instance == null) {
            synchronized (LogHelper.class) {
                if (instance == null) {
                    instance = new LogHelper();
                }
            }
        }
        return instance;
    }

    private LogHelper() {
    }

    //日志类型
    public enum TYPE {
        //流水
        verbose,
        //常规
        info,
        //错误
        error,
    }

    //日志存储缓存最大长度
    private long saveMaxSize = 1024 * 1024;
    //如果为null 表示不存入本地
    private String savePath = null;
    private StringBuffer verboseLog = new StringBuffer();
    private StringBuffer infoLog = new StringBuffer();
    private StringBuffer errorLog = new StringBuffer();
    /**
     * 保存文件的时间 不设置默认为系统时间
     */
    private long saveTime = 0;
    /**
     * 文件名称前缀
     */
    private String fileTag = "";

    private DateFormat fileNameFormatter = MyDateTimeUtil.getMyDateFormat("yyyy-MM-dd-HH-mm-ss");
    private DateFormat logTimeFormatter = MyDateTimeUtil.getMyDateFormat("yyyy-MM-dd-HH-mm-ss");

    public void setSaveTime(long saveTime) {
        this.saveTime = saveTime;
    }

    public void setFileTag(String fileTag) {
        this.fileTag = fileTag;
    }

    public void verbose(String s) {
        verbose(s, true, true);
    }

    /**
     * @param s        日志
     * @param isUpload 是否上传到文件
     * @param isTime   是否添加时间
     */
    public void verbose(String s, boolean isUpload, boolean isTime) {
        if (isTime) {
            verboseLog.append(logTimeFormatter.format(new Date())).append(":  ");
        }
        verboseLog.append(s).append("\n");
        if (verboseLog.length() > saveMaxSize && isUpload) {
            String log = verboseLog.toString();
            verboseLog = new StringBuffer();
            saveLogToFileThread(log, TYPE.verbose);
        }
    }

    public void info(String s) {
        info(s, true, true);
    }

    public void info(String s, boolean isUpload, boolean isTime) {
        if (isTime) {
            infoLog.append(logTimeFormatter.format(new Date())).append(":  ");
        }
        infoLog.append(s).append("\n");
        if (infoLog.length() > saveMaxSize && isUpload) {
            String log = infoLog.toString();
            infoLog = new StringBuffer();
            saveLogToFileThread(log, TYPE.info);
        }
    }

    public void error(String s) {
        error(s, true, true);
    }

    public void error(String s, boolean isUpload, boolean isTime) {
        if (isTime) {
            errorLog.append(logTimeFormatter.format(new Date())).append(":  ");
        }
        errorLog.append(s).append("\n");
        if (errorLog.length() > saveMaxSize && isUpload) {
            String log = errorLog.toString();
            errorLog = new StringBuffer();
            saveLogToFileThread(log, TYPE.error);
        }
    }

    private void saveLogToFileThread(final String log, final TYPE type) {
        new Thread(() -> saveLogToFile(log, type)).start();
    }

    private synchronized void saveLogToFile(String log, TYPE type) {
        String time = fileNameFormatter.format(new Date());
        if (saveTime != 0) {
            time = fileNameFormatter.format(saveTime);
        }
        String fileName = fileTag + "-log-" + time + ".txt";
        switch (type) {
            case verbose:
                fileName = fileTag + "-verbose-" + time + ".txt";
                break;
            case info:
                fileName = fileTag + "-info-" + time + ".txt";
                break;
            case error:
                fileName = fileTag + "-error-" + time + ".txt";
                break;
        }
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && savePath != null) {
            MyFileUtil.saveFile(savePath, fileName, log.getBytes(), true);
        }
    }

    /**
     * 存储所有日志
     */
    public void saveAllLog() {
        new Thread(this::saveAllLogOnMain).start();
    }

    public void saveAllLogOnMain() {
        if (verboseLog.length() > 0) {
            String log = verboseLog.toString();
            verboseLog = new StringBuffer();
            saveLogToFile(log, TYPE.verbose);
        }
        if (infoLog.length() > 0) {
            String log = infoLog.toString();
            infoLog = new StringBuffer();
            saveLogToFile(log, TYPE.info);
        }
        if (errorLog.length() > 0) {
            String log = errorLog.toString();
            errorLog = new StringBuffer();
            saveLogToFile(log, TYPE.error);
        }
    }

    public void setSaveMaxSize(long saveMaxSize) {
        this.saveMaxSize = saveMaxSize;
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }

    public String getSavePath() {
        return savePath;
    }

    public DateFormat getFileNameFormatter() {
        return fileNameFormatter;
    }

    /**
     * 文件日期格式，不要用空格
     *
     * @param fileNameFormatter
     */
    public void setFileNameFormatter(DateFormat fileNameFormatter) {
        this.fileNameFormatter = fileNameFormatter;
    }

    public DateFormat getLogTimeFormatter() {
        return logTimeFormatter;
    }

    public void setLogTimeFormatter(DateFormat logTimeFormatter) {
        this.logTimeFormatter = logTimeFormatter;
    }
}
